
//*************** 基本用法  *****************/

const promise = new Promise(function (resolve, reject) {
    // ... some code
    if (true) {
        resolve(value);
    } else {
        reject(error);
    }
});


// Promise 新建后就会立即执行
let promise = new Promise(function (resolve, reject) {
    console.log('Promise');
    resolve();
});
setTimeout(() => {
    // 也能触发
    promise.then(function () {
        console.log('resolved.');
    });
}, 1000)


//*************** 内部引用另外的Promise  *****************/

const p1 = new Promise(function (resolve, reject) {
    // ...
    resolve()
});

const p2 = new Promise(function (resolve, reject) {
    // ...
    resolve(p1); //p1绝定了p2的状态 （这里会等待p1，如果p1失败 那么p2也失败）
})


p2.then(() => {
    console.log('成功了')
}).catch(() => {
    console.log('失败了')
})


//*************** Promise.prototype.then()  *****************/

const promise = new Promise(function (resolve, reject) {
    true ? resolve(value) : reject(error)
})

promise
    .then(function (data) {       //监控成功状态
        data.name = '小红'
        data.age = 18
        return data
    })
    .then(function (data) {       //监控成功状态
        console.log(data)
    })
    .catch(function (error) {     //监控失败状态

    })
    .finally(function (error) {   //不管状态 都会执行这个

    })

//*************** Promise.allSettled()   *****************/
//* 方法接受一组 Promise 实例作为参数，包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果，
//* 不管是fulfilled还是rejected，包装实例才会结束。该方法由 ES2020 引入。
const promises = [
    fetch('/api-1'),
    fetch('/api-2'),
    fetch('/api-3'),
];

await Promise.allSettled(promises);


//*************** Pomise.all  *****************/

let p1 = new Promise((resolve, reject) => {
    resolve('成功了')
})

let p2 = new Promise((resolve, reject) => {
    resolve('success')
})

let p3 = Promse.reject('失败')

Promise.all([p1, p2]).then((result) => {
    console.log(result)               //['成功了', 'success']
}).catch((error) => {
    console.log(error)
})

Promise.all([p1, p3, p2]).then((result) => {
    console.log(result)
}).catch((error) => {
    console.log(error)      // 失败了，打出 '失败'
})


//*************** Promise.any()  *****************/

const promises = [
    fetch('/endpoint-a').then(() => 'a'),
    fetch('/endpoint-b').then(() => 'b'),
    fetch('/endpoint-c').then(() => 'c'),
];
try {
    const first = await Promise.any(promises);
    console.log(first);
} catch (error) {
    console.log(error);
}


//*************** Generator 函数与 Promise 的结合  *****************/

function getFoo() {
    return new Promise(function (resolve, reject) {
        resolve('foo');
    });
}

const g = function* () {
    try {
        const foo = yield getFoo();
        console.log(foo);
    } catch (e) {
        console.log(e);
    }
};

function run(generator) {
    const it = generator();

    function go(result) {
        if (result.done) return result.value;

        return result.value.then(function (value) {
            return go(it.next(value));
        }, function (error) {
            return go(it.throw(error));
        });
    }

    go(it.next());
}

run(g);


//*************** Promise.try()  *****************/
// ，Promise 库Bluebird、Q和when，早就提供了这个方法。
//*  事实上，Promise.try就是模拟try代码块，就像promise.catch模拟的是catch代码块。
Promise.try(() => database.users.get({ id: userId }))
    .then(...)
    .catch(...)